package org.yelongframework.mybatis.mapper;

import java.util.Map;

import org.yelongframework.core.pair.Pairs;
import org.yelongframework.core.util.map.AttrMap;

/**
 * 通用注解映射参数。 参数的键值中必须要有 {@link GenericMapper#SQL_ID} 的键。如果需要参数，为防止SQL注入，建议如下：
 * {sql = update user set username = #{username} where id = #{id} , id = "01" ,
 * username = "xiaoming"} 这种场景参数占位符不支持 $，必须使用#
 * 
 * @since 1.0.0
 */
public class GenericMapperParam extends AttrMap {

	private static final long serialVersionUID = 2094605968542213704L;

	/** 参数索引与名称对 */
	private Pairs<Integer, String> paramIndexNamePairs = new Pairs<>();

	// ==================================================constructor==================================================

	public GenericMapperParam() {
	}

	/**
	 * @param sql SQL语句
	 */
	public GenericMapperParam(String sql) {
		setSql(sql);
	}

	/**
	 * @param params SQL参数
	 */
	public GenericMapperParam(Map<String, Object> params) {
		putAll(params);
	}

	/**
	 * @param sql    SQL语句
	 * @param params SQL参数
	 */
	public GenericMapperParam(String sql, Map<String, Object> params) {
		setSql(sql);
		putAll(params);
	}

	// ==================================================sql==================================================

	/**
	 * @param sql SQL语句
	 */
	public void setSql(String sql) {
		put(GenericMapper.SQL_ID, sql);
	}

	/**
	 * @return SQL语句
	 */
	public String getSql() {
		return getString(GenericMapper.SQL_ID);
	}

	// ==================================================put==================================================

	/**
	 * 添加一个参数值
	 * 
	 * @param paramIndex 参数索引
	 * @param paramName  参数名称
	 * @param paramValue 参数值
	 * @return 参数值
	 */
	public Object put(int paramIndex, String paramName, Object paramValue) {
		addParamIndexNamePair(paramIndex, paramName);
		return super.put(paramName, paramValue);
	}

	// ==================================================paramIndexNamePairs==================================================

	/**
	 * 添加一个参数索引与名称对
	 * 
	 * @param paramIndex 参数索引
	 * @param paramName  参数名称
	 * @return this
	 */
	public GenericMapperParam addParamIndexNamePair(int paramIndex, String paramName) {
		paramIndexNamePairs.add(paramIndex, paramName);
		return this;
	}

	/**
	 * 根据参数名称获取参数索引位置
	 * 
	 * @param paramName 参数名称
	 * @return 参数索引
	 */
	public Integer getParamIndexByParamName(String paramName) {
		return paramIndexNamePairs.getLeftByRight(paramName);
	}

	/**
	 * 根据参数索引获取参数名称
	 * 
	 * @param paramIndex 参数索引
	 * @return 参数名称
	 */
	public String getParamNameByParamIndex(int paramIndex) {
		return paramIndexNamePairs.getRightByLeft(paramIndex);
	}

	/**
	 * @return 参数索引与名称对集合
	 */
	public Pairs<Integer, String> getParamIndexNamePairs() {
		return paramIndexNamePairs;
	}

}
